// a17_TaskAsyncPattern.Program
#define DEBUG
using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using a17_TaskAsyncPattern;

internal class Program
{
	[StructLayout(LayoutKind.Auto)]
	[CompilerGenerated]
	private struct _003CAddAsync_003Ed__3 : IAsyncStateMachine
	{
		public int _003C_003E1__state;

		public AsyncTaskMethodBuilder<int> _003C_003Et__builder;

		public int a;

		public int b;

		public Func<int> _003Cdg_003E5__4;

		public int _003Csum_003E5__5;

		public _003C_003Ec__DisplayClass1 CS_0024_003C_003E8__locals2;

		private TaskAwaiter<int> _003C_003Eu___0024awaiter6;

		private object _003C_003Et__stack;

		private void MoveNext()
		{
			int result2 = default(int);
			try
			{
				bool flag = true;
				TaskAwaiter<int> awaiter;
				switch (_003C_003E1__state)
				{
				case -3:
					goto end_IL_0000;
				default:
					CS_0024_003C_003E8__locals2 = new _003C_003Ec__DisplayClass1();
					CS_0024_003C_003E8__locals2.a = a;
					CS_0024_003C_003E8__locals2.b = b;
					Debug.WriteLine("AddAsync 1, tid=" + Thread.CurrentThread.ManagedThreadId);
					_003Cdg_003E5__4 = () => Add(CS_0024_003C_003E8__locals2.a, CS_0024_003C_003E8__locals2.b);
					Debug.WriteLine("AddAsync 2, tid=" + Thread.CurrentThread.ManagedThreadId);
					awaiter = Task.Run(_003Cdg_003E5__4).GetAwaiter();
					if (!awaiter.IsCompleted)
					{
						_003C_003E1__state = 0;
						_003C_003Eu___0024awaiter6 = awaiter;
						_003C_003Et__builder.AwaitUnsafeOnCompleted(ref awaiter, ref this);
						flag = false;
						return;
					}
					break;
				case 0:
					awaiter = _003C_003Eu___0024awaiter6;
					_003C_003Eu___0024awaiter6 = default(TaskAwaiter<int>);
					_003C_003E1__state = -1;
					break;
				}
				int result = awaiter.GetResult();
				awaiter = default(TaskAwaiter<int>);
				int num = (_003Csum_003E5__5 = result);
				Debug.WriteLine("AddAsync 3, tid=" + Thread.CurrentThread.ManagedThreadId);
				result2 = _003Csum_003E5__5;
				end_IL_0000:;
			}
			catch (Exception exception)
			{
				_003C_003E1__state = -2;
				_003C_003Et__builder.SetException(exception);
				return;
			}
			_003C_003E1__state = -2;
			_003C_003Et__builder.SetResult(result2);
		}

		void IAsyncStateMachine.MoveNext()
		{
			//ILSpy generated this explicit interface implementation from .override directive in MoveNext
			this.MoveNext();
		}

		[DebuggerHidden]
		private void SetStateMachine(IAsyncStateMachine param0)
		{
			_003C_003Et__builder.SetStateMachine(param0);
		}

		void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine param0)
		{
			//ILSpy generated this explicit interface implementation from .override directive in SetStateMachine
			this.SetStateMachine(param0);
		}
	}

	private static void Main(string[] args)
	{
		int sum = 0;
		Debug.WriteLine("call Sync, tid=" + Thread.CurrentThread.ManagedThreadId);
		sum = AddSync(1, 2);
		Debug.WriteLine("Sync result=" + sum);
		Debug.WriteLine("call Async, tid=" + Thread.CurrentThread.ManagedThreadId);
		Task<int> t = AddAsync(3, 4);
		Debug.WriteLine("task wait, tid=" + Thread.CurrentThread.ManagedThreadId);
		t.Wait();
		Debug.WriteLine("Async result=" + t.Result + ", tid=" + Thread.CurrentThread.ManagedThreadId);
	}

	private static int Add(int a, int b)
	{
		Debug.WriteLine("Add(), tid=" + Thread.CurrentThread.ManagedThreadId);
		return a + b;
	}

	private static int AddSync(int a, int b)
	{
		return Add(a, b);
	}

	[DebuggerStepThrough]
	[AsyncStateMachine(typeof(_003CAddAsync_003Ed__3))]
	private static Task<int> AddAsync(int a, int b)
	{
		_003CAddAsync_003Ed__3 stateMachine = default(_003CAddAsync_003Ed__3);
		stateMachine.a = a;
		stateMachine.b = b;
		stateMachine._003C_003Et__builder = AsyncTaskMethodBuilder<int>.Create();
		stateMachine._003C_003E1__state = -1;
		AsyncTaskMethodBuilder<int> _003C_003Et__builder = stateMachine._003C_003Et__builder;
		_003C_003Et__builder.Start(ref stateMachine);
		return stateMachine._003C_003Et__builder.Task;
	}
}
